package drds.common.db.sql_mapping.sql_execute;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;

public class MapperProxy<T> implements InvocationHandler {

    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethod> methodToMapperMethodMap;
    //
    private final MapperExecutionContext mapperExecutionContext;

    public MapperProxy(Class<T> mapperInterface, Map<Method, MapperMethod> methodToMapperMethodMap, MapperExecutionContext mapperExecutionContext) {
        this.mapperInterface = mapperInterface;
        this.methodToMapperMethodMap = methodToMapperMethodMap;
        //
        this.mapperExecutionContext = mapperExecutionContext;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            if (Object.class.equals(method.getDeclaringClass())) {
                return method.invoke(this, args);
            } else if (method.isDefault()) {
                throw new RuntimeException("Mapper 接口不支持默认方法");
            }
        } catch (Exception t) {
            throw new RuntimeException(t);
        }
        final MapperMethod mapperMethod = cachedMapperMethod(method);
        return mapperMethod.execute(mapperExecutionContext, method, args);
    }


    private MapperMethod cachedMapperMethod(Method method) {
        return methodToMapperMethodMap.computeIfAbsent(method, key -> new MapperMethod(mapperExecutionContext.getConfiguration(), mapperInterface, method));
    }


}
